<a href="https://github.com/socketstream/socketstream/edit/master/src/docs/tutorials/en/rpc_responder.ngdoc" class="improve-docs"><i class="icon-edit"> </i>Improve this doc</a><h1><code ng:non-bindable=""></code>
<div><span class="hint"></span>
</div>
</h1>
<div><div class="rpc-websocket-responder-page"><h2 id="rpc-server-side-websocket-responder">RPC Server-side Websocket Responder</h2>
<p>The RPC Responder allows you to call functions on the server from the browser over the websocket, returning a response if requested. It is powerful when used in conjunction with <a href="#/tutorials/request_middleware">Request Middleware</a>.</p>
<p>To make a Remote Procedure Call from the browser use the <code>ss.rpc()</code> function.</p>
<p>Let&#39;s assume we want to return an array of the latest products in an online store. We would want to call the following command from the browser:</p>
<pre class="prettyprint linenums">
ss.rpc('products.latest', function(result){ console.log('The latest products are:', result); })
</pre>
<p>This command will be sent over the websocket and sent directly to the RPC Responder. But how will it know which function to call on the server?</p>
<p>The RPC responder loads all commands in <code>server/rpc</code> into an API Tree. Thus the command to call &#39;products.latest&#39; will be matched to the &#39;latest&#39; function in the &#39;products&#39; file <code>/server/rpc/products.js</code>.</p>
<p>The <code>products.js</code> file should contain the available actions as so:</p>
<pre class="prettyprint linenums">
// server/rpc/products.js
exports.actions = function(req, res, ss) {
  return {
    latest: function(){
      res(['iPhone 4S', 'Dell LCD TV', 'HP Printer']);
    }
  }
};
</pre>
<h4 id="rpc-server-side-websocket-responder_sending-arguments">Sending Arguments</h4>
<p>The RPC Responder can take and return unlimited arguments intuitively. For example let&#39;s write another action on the server:</p>
<pre class="prettyprint linenums">
// server/rpc/products.js
exports.actions = function(req, res, ss) {
  return {
    topSelling: function(startDate, endDate, productType){
      // do calculations then send multiple args back to client...
      res(['iPad', 'iPhone', ...], 'Scooby Doo');
    },
    latest: function(){
      res(['iPhone', 'Dell LCD TV', 'HP Printer']);
    }
  }
};
</pre>
<p>To call this from the browser we&#39;d use:</p>
<pre class="prettyprint linenums">
// client/code/main/products.js
var productType = 'electronics';
ss.rpc('products.topSelling', '2012-01-01', '2012-01-31', productType, function(products, bestSalesperson) {
  console.log('The top selling products in ' + productType + ' were:', products);
  console.log('And the best salesperson was:', bestSalesperson);
});
</pre>
<p>The ability to pass multiple arguments also means you can choose to follow the &#39;error first&#39; idiom typically used in Node:</p>
<pre class="prettyprint linenums">
// client/code/main/products.js
ss.rpc('products.add', 123, function(err, data) {
  if (err) {
    return alert("Error adding product!");
  }
  $('#products').append( ss.tmpl['product.details'].render(data) );
});
</pre>
<p>You may pass as many arguments as you want - just remember the last argument should always be the callback if you&#39;re expecting a response from the server.</p>
<h4 id="rpc-server-side-websocket-responder_how-can-i-call-a-mongoose/redis/db/rest-api-from-my-rpc-actions">How can I call a Mongoose/Redis/DB/REST API from my RPC actions?</h4>
<p>Require the module you need in your main <code>/app.js</code> file then add it to the &#39;internal API&#39;:</p>
<pre class="prettyprint linenums">
// in /app.js
var db   = require('mydb'),
    conn = db.createConnection();

ss.api.add('db', conn);
</pre>
<p>You may now access this DB connection in your <code>/server/rpc</code> methods with <code>ss.db</code>.</p>
<h4 id="rpc-server-side-websocket-responder_how-does-it-work-under-the-hood">How does it work under the hood?</h4>
<p>The RPC Responder serializes messages in both directions using JSON. Thus the actual message sent over the wire is a string which looks like this:
<pre class="prettyprint linenums">
    {id: 1, m: 'method.to.call', p: [param1, param2, ...]}
</pre>
<h4 id="rpc-server-side-websocket-responder_how-can-i-call-an-rpc-action-from-a-server-side-file">How can I call an RPC action from a server-side file?</h4>
<p>RPC actions are strictly called via the client-side.</p>
<p>If you have business logic that you&#39;d like to share between both the client and server sides, we recommend you create a new <code>node_module</code> as so:</p>
<pre class="prettyprint linenums">
// in /node_modules/myModule/myModule.js
myModule = function() {
  sharedFunction: function() {
    return "shared function called";
  }
};

exports.myModule = myModule();
</pre>
<pre class="prettyprint linenums">
// in /app.js
myModule = require('myModule').myModule();

myModule.sharedFunction(); // returns "shared function called"
</pre>
<pre class="prettyprint linenums">
// in /rpc/demo.js
myModule = require('myModule').myModule();

exports.actions = function(req, res, ss) {
  callSharedFunction: function() {
    myModule.sharedFunction(); // returns "shared function called"
  }
};
</pre>
</div></div>
